package com.rrd.hive.udf;

import java.io.RandomAccessFile;
import java.net.URI;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hive.ql.exec.UDF;

import com.rrd.hive.udf.iptoarea.RRDAreaFile;
import com.rrd.hive.udf.iptoarea.RRDAreaRecord;

public class UDFIpToArea extends UDF {
    RRDAreaFile rrdAreaFile = null;

    public String evaluate(String ip) throws Exception {
        if (ip == null) {
            return " ";
        }
        if (this.rrdAreaFile == null) {
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem
                .newInstance(URI.create("/user/hdfs/udf/iplib.dat"), conf);
            fs.copyToLocalFile(false, new Path("/user/hdfs/udf/iplib.dat"),
                new Path("/tmp/udf/iplib.dat"));
            this.rrdAreaFile = RRDAreaFile.getInstance("/tmp/udf/iplib.dat");
        }

        RandomAccessFile ipFile = this.rrdAreaFile.getIpFile();
        RRDAreaRecord record = this.rrdAreaFile.find(ip, ipFile);

        String country = this.string2Unicode(record.getCountry());
        return this.unicode2String(
            country.replaceAll("\\\\u7701", "\\\\u7701\\\\u0020"));
    }

    private String string2Unicode(String string) {
        StringBuffer unicode = new StringBuffer();
        for (int i = 0; i < string.length(); i++) {
            // 取出每一个字符
            char c = string.charAt(i);
            // 转换为unicode
            unicode.append("\\u" + Integer.toHexString(c));
        }
        return unicode.toString();
    }

    private String unicode2String(String unicode) {
        if (StringUtils.isBlank(unicode)) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        int i = -1;
        int pos = 0;

        while ((i = unicode.indexOf("\\u", pos)) != -1) {
            sb.append(unicode.substring(pos, i));
            if (i + 5 < unicode.length()) {
                pos = i + 6;
                sb.append((char) Integer
                    .parseInt(unicode.substring(i + 2, i + 6), 16));
            }
        }

        if (sb.toString().split(" ", -1).length != 2) {
            return sb.toString() + " ";
        }
        return sb.toString();
    }

    public static void main(String[] args) throws Exception {

        String args1 = "218.62.46.226";
        UDFIpToArea dfu = new UDFIpToArea();
        System.out.println(dfu.evaluate(args1));

    }
}
